package open.panxiong.shared.util

import android.annotation.SuppressLint
import android.app.NotificationManager
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.util.Log
import android.widget.Toast
import androidx.annotation.RequiresApi
import com.google.zxing.BarcodeFormat
import com.google.zxing.MultiFormatWriter
import com.google.zxing.WriterException
import com.journeyapps.barcodescanner.BarcodeEncoder
import java.io.File
import java.io.FileOutputStream
import java.net.NetworkInterface
import java.text.SimpleDateFormat
import java.util.*


/**
 * 是否图片视频
 */
fun isMediaFile(fileName: String): Boolean {
    return isImageFile(fileName) || isVideoFile(fileName)
}

fun isImageFile(fileName: String): Boolean {
    return fileName.lowercase().endsWith(".png") ||
            fileName.lowercase().endsWith(".jpg") ||
            fileName.lowercase().endsWith(".jpeg") ||
            fileName.lowercase().endsWith(".bmp") ||
            fileName.lowercase().endsWith(".webp")
}

fun isVideoFile(fileName: String): Boolean {
    return fileName.lowercase().endsWith(".mp4") ||
            fileName.lowercase().endsWith(".3gp") ||
            fileName.lowercase().endsWith(".wmv") ||
            fileName.lowercase().endsWith(".ts") ||
            fileName.lowercase().endsWith(".rmvb") ||
            fileName.lowercase().endsWith(".mov") ||
            fileName.lowercase().endsWith(".m4v") ||
            fileName.lowercase().endsWith(".avi") ||
            fileName.lowercase().endsWith(".mkv") ||
            fileName.lowercase().endsWith(".flv") ||
            fileName.lowercase().endsWith(".divx") ||
            fileName.lowercase().endsWith(".f4v") ||
            fileName.lowercase().endsWith(".rm") ||
            fileName.lowercase().endsWith(".asf") ||
            fileName.lowercase().endsWith(".ram") ||
            fileName.lowercase().endsWith(".mpg") ||
            fileName.lowercase().endsWith(".v8") ||
            fileName.lowercase().endsWith(".swf") ||
            fileName.lowercase().endsWith(".m2v") ||
            fileName.lowercase().endsWith(".asx") ||
            fileName.lowercase().endsWith(".ra") ||
            fileName.lowercase().endsWith(".ndivx") ||
            fileName.lowercase().endsWith(".xvid") ||
            fileName.lowercase().endsWith(".gif")
}

@SuppressLint("SimpleDateFormat")
fun getDateString(pattern: String = "yyyy-MM-dd_HHmmss"): String {
    return SimpleDateFormat(pattern).format(Date()).toString()
}

fun getIpV4Address(): String {
    try {
        val networkInterface = Collections.list(NetworkInterface.getNetworkInterfaces())
        for (network in networkInterface) {
            val inetAddress = Collections.list(network.inetAddresses)
            for (address in inetAddress) {
                if (!address.isLoopbackAddress) {
                    val sAdder = address.hostAddress ?: continue
                    if (sAdder.indexOf(':') < 0) return sAdder
                }
            }
        }
    } catch (e: Exception) {
        Log.e("TOOLS", "获取IP地址出错", e)
    }
    return ""
}

fun createQRCodeBitmap(content: String): Bitmap? {
    return try {
        val multiFormatWriter = MultiFormatWriter()
        val bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 500, 500)
        val barcodeEncoder = BarcodeEncoder()
        barcodeEncoder.createBitmap(bitMatrix)
    } catch (e: WriterException) {
        null
    }
}

@SuppressLint("DefaultLocale")
fun byteToShowText(byte: Long): String {
    return if (byte > (1024 * 1024 * 1024)) {
        String.format("%.2f", (byte / (1024 * 1024 * 1024.0))) + " G"
    } else if (byte > (1024 * 1024)) {
        String.format("%.2f", (byte / (1024 * 1024.0))) + " M"
    } else if (byte > 1024) {
        String.format("%.2f", (byte / 1024.0)) + " k"
    } else {
        "${String.format("%.2f", byte)} b"
    }
}

// 创建文件并保存Bitmap
@RequiresApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
fun saveImageToGallery(context: Context, file: File) {
    val bitmap = BitmapFactory.decodeFile(file.absolutePath)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        val values = ContentValues()
        values.put(MediaStore.Images.Media.DISPLAY_NAME, file.name)
        if (file.name.endsWith(".jpg")) {
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
        } else if (file.name.endsWith(".webp")) {
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/webp")
        } else if (file.name.endsWith(".gif")) {
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/gif")
        } else {    // file.name.endsWith(".png")
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/png")
        }
        values.put(
            MediaStore.Images.Media.RELATIVE_PATH,
            Environment.DIRECTORY_PICTURES + "/And-Share"
        )
        try {
            val uri = context.contentResolver.insert(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values
            ) ?: return
            val outputStream = context.contentResolver.openOutputStream(uri)
            if (outputStream != null) {
                if (file.name.endsWith(".jpg")) {
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
                } else if (file.name.endsWith(".webp")) {
                    bitmap.compress(Bitmap.CompressFormat.WEBP, 100, outputStream)
                } else {    // file.name.endsWith(".png")
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
                }
                outputStream.close()
            }
        } catch (e: Exception) {
            Log.e("TOOLS", "保存图片到图库失败", e)
        }
    } else {
        val filePath = Environment.getExternalStorageDirectory().path + "/And-Share/${file.name}"
        try {
            val outputStream = FileOutputStream(File(filePath))
            if (file.name.endsWith(".jpg")) {
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
            } else if (file.name.endsWith(".webp")) {
                bitmap.compress(Bitmap.CompressFormat.WEBP, 100, outputStream)
            } else {    // file.name.endsWith(".png")
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
            }
            outputStream.close()
            // 发送广播通知图库更新
            val scanIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
            val contentUri = Uri.fromFile(file)
            scanIntent.setData(contentUri)
            context.sendBroadcast(scanIntent)
        } catch (e: Exception) {
            Log.e("TOOLS", "保存图片到图库失败", e)
        }
    }
}


// 删除目录与目录内部文件
fun deleteDirectory(directory: File?) {
    if (directory?.isDirectory == true) {
        directory.listFiles()?.forEach {
            deleteDirectory(it)
        }
    }
    directory?.delete()
}

fun showToast(context: Context, msg: String) {
    Toast.makeText(context, msg, Toast.LENGTH_LONG).show()
}

fun getZipFileName(names: List<String>): String {
    var name = names.toTypedArray().joinToString(separator = "_") { it }
    if (name.length > 32) {
        name = name.substring(0, 32)
    }
    name = name.replace(".", "_")
    return "${name}_等${names.size}个文件_${getDateString("HHmmss")}.zip"
}

// 根据URI获取文件名
fun getFileNameFromUri(context: Context, uri: Uri): String {
    val cursor = context.contentResolver.query(uri, null, null, null, null)
        ?: return System.currentTimeMillis().toString()
    val nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)
    cursor.moveToFirst()
    val fileName = cursor.getString(nameIndex)
    cursor.close()
    return fileName ?: System.currentTimeMillis().toString()
}

/**
 * 检查对应ID的通知是否存在
 */
fun isNotificationExists(context: Context, notificationId: Int): Boolean {
    val notificationManager =
        context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    val activeNotifications = notificationManager.activeNotifications
    return (activeNotifications != null &&
            activeNotifications.isNotEmpty() &&
            activeNotifications[0].id == notificationId)
}


/**
 * 打开浏览器显示共享文件
 */
fun openBrowserViews(context: Context, url: String) {
    val intent = Intent(Intent.ACTION_VIEW).apply {
        data = Uri.parse(url)
    }
    context.startActivity(intent)
}